#include<iostream>
#include<queue>
using namespace std;
const int N = 1e6 + 10;
int main()
{
	priority_queue<int,vector<int>,greater<int>> tree;
	int n;cin >> n;
	for (int i = 1; i <= n; i++)
	{
		int op;cin >> op;
		switch (op)
		{
		case 1:int po;cin >> po;
			tree.push(po);break;
		case 2:cout << tree.top() << endl;break;
		case 3:tree.pop();break;
		}
	}
	return 0;
}
//#include<iostream>
//#include<vector>
//#include<algorithm>
//using namespace std;
//const int N = 1e6 + 10;
//int heap[N];
//int fa[N], dis[N],n;
//void up(int child)
//{
//	int parent = child / 2;
//		while (parent >= 1 && heap[parent] > heap[child])
//		{
//			swap(heap[parent], heap[child]); 
//			child = parent;
//			parent = child / 2;
//
//		}
//	}
//void down(int parent)
//{
//	int child = parent * 2;
//	while (child <= n)
//	{
//		if (child + 1 <= n && heap[child]  >  heap[child + 1]) child++;
//		if (heap[parent] <= heap[child]) return;
//		swap(heap[child], heap[parent]);
//		parent = child;
//		child = parent * 2;
//	}
//}
//void push(int x)
//{
//	heap[++n] = x; 
//	up(x);
//}
//void top()
//{
//	cout << heap[1] << endl;
//}
//void erase()
//{
//	swap(heap[1], heap[n]);
//	n--;
//	down(1);
//}
//int main()
//{
//	int n;cin >> n;
//	for (int i = 1; i <= n; i++)
//	{
//		int op = 0;cin >> op;
//		switch (op)
//		{
//			int po;
//		case 1:cin >> po;push(po);break;
//		case 2:top();break;
//		case 3:erase();break;
//		}
//	}
//	return 0;
//}